package main

import (
	"fmt"
	"github.com/panjf2000/gnet"
	"gnet_bug_demo/common"
	"math/rand"
	"os"
	"os/signal"
)

type NetHandler struct {
	*gnet.EventServer
}

func (*NetHandler) React(frame []byte, c gnet.Conn) (out []byte, action gnet.Action) {
	go func(frame []byte, c gnet.Conn) {
		// 模拟业务耗时
		for i := 0; i < 10000; i++ {
			_ = rand.Float64()
		}
		if checkFrameLength(&frame) {
			/**
			这个问题在windows和linux都有出现
			异常结果见截图： 数据报打印异常结果.png
			*/
			fmt.Println(frame[0])
		}
		if c.RemoteAddr() == nil {
			/**
			在windows下没有问题，但是在linux会
			异常结果见截图： RemoteAddr返回nil.png
			*/
			panic("RemoteAddr is nil!")
		}
	}(frame, c)
	return
}

// checkFrameLength 检验长度是否合法
func checkFrameLength(frame *[]byte) bool {
	return len(*frame) == common.DatagramSize
}

func main() {
	go gnet.Serve(new(NetHandler), fmt.Sprintf("udp://%s:%d", common.ServerHost, common.ServerPort), gnet.WithMulticore(true))

	exitOnSignal()
}

// exitOnSignal 监听退出信号
func exitOnSignal() {
	quit := make(chan os.Signal)
	signal.Notify(quit, os.Interrupt)

	select {
	case <-quit:
		// nop
	}
}
